#define _GNU_SOURCE // 如是不声明gettid()不识别报错
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

/*
#define _GNU_SOURCE
请求编译器启用GNU libc（GNU C库）中所有的扩展特性

gettid函数并不是标准C库或POSIX线程库（pthreads）直接提供的函数，而是Linux内核中的一个系统调用。
由于它没有在像glibc这样的标准C库中声明，所以在用户空间代码中直接使用gettid时，编译器会报未定义的错误。
*/

/*
作用：创建一个线程
参数1：线程标识符的指针,线程创建成功时,用于存储新创建线程的线程标识符
参数2：pthead_attr_t结构体,这个参数可以用来设置线程的属性,如优先级、栈大小等。
      如果不需要定制线程属性,可以传入 NULL,此时线程将采用默认属性。
参数3：新线程函数的指针
参数4：函数的参数,可以是一个指向任意类型数据的指针
返回值：成功：0,失败非0
int pthread_create(pthread_t *thread, const pthread_attr_t *attr
    ,void *(*start_routine)(void *), void *arg);
 */

// 第一个分线程函数
void * thread_first (void *argv)
{
    printf("thread_first线程（%d）开始执行了 \n", gettid());
    // first线程休眠1秒 =》 CPU就会切换到其它线程执行
    sleep(1);
    printf("thread_first线程又开始执行了 \n");
}

// 第二个分线程函数
void * thread_second (void *argv)
{
    printf("thread_second线程（%d）开始执行了 \n", gettid());
}

int main(int argc, char const *argv[])
{
    printf("main线程(%d)开始执行 \n", gettid());

    // 定义存储线程标识的变量
    pthread_t thread_f;
    pthread_t thread_s;

    // 创建两个分线程
    pthread_create(&thread_f, NULL, thread_first, NULL);
    pthread_create(&thread_s, NULL, thread_second, NULL);

    printf("main线程继续执行 thread_f=%ld, thread_s=%ld\n", thread_f, thread_s);

    // 等待分线程执行完成
    pthread_join(thread_f, NULL);
    pthread_join(thread_s, NULL);

    printf("main线程即将结束 \n");

    return 0;
}
